<template>
    <a-modal v-model:visible="visibleProxy" :footer="null" :keyboard="false" :mask-closable="false" :width="520"
        :title="null" :closable="false" centered class="import-modal">
        <div class="im-header">
            <div class="title">{{ title }}</div>
            <a class="close" role="button" @click.stop.prevent="visibleProxy = false">关闭</a>
        </div>

        <div class="im-body">
            <div class="row">
                <div class="label">选择文件</div>
                <div class="value">
                    <template v-if="!file">
                        <a-button size="small" class="primary-lite" @click="triggerPick">选择文件</a-button>
                        <input ref="fileInput" :accept="accept" type="file" style="display:none"
                            @change="onFileChange" />
                    </template>
                    <template v-else>
                        <a :title="file.name">{{ file.name }}</a>
                        <a class="link-del" role="button" @click.stop.prevent="removeFile">删除</a>
                    </template>
                    <div class="tip">{{ tip }}</div>
                </div>
            </div>
        </div>

        <div class="im-footer">
            <a-button type="link" class="cancel" @click.stop.prevent="visibleProxy = false">取消</a-button>
            <span class="sep">|</span>
            <a-button type="link" class="confirm" :disabled="!file" @click.stop.prevent="confirm">导入</a-button>
        </div>
    </a-modal>
</template>

<script lang="ts" setup>
import { ref, computed, watch } from 'vue'

const props = withDefaults(defineProps<{
    modelValue: boolean
    title?: string
    accept?: string
    tip?: string
}>(), {
    title: '导入',
    accept: '.csv,.json,application/json,text/csv',
    tip: '支持 CSV 或 JSON（UTF-8）。'
})

const emit = defineEmits<{
    (e: 'update:modelValue', v: boolean): void
    (e: 'import', file: File): void
}>()

const visibleProxy = computed({
    get: () => props.modelValue,
    set: v => emit('update:modelValue', v)
})

const file = ref<File | null>(null)
const fileInput = ref<HTMLInputElement | null>(null)

/* 打开弹窗自动重置文件选择 */
watch(() => props.modelValue, v => {
    if (v) { file.value = null; if (fileInput.value) fileInput.value.value = '' }
})

function triggerPick() { fileInput.value?.click() }
function onFileChange(e: Event) { const t = e.target as HTMLInputElement; if (t.files?.length) file.value = t.files[0] }
function removeFile() { file.value = null; if (fileInput.value) fileInput.value.value = '' }
function confirm() { if (file.value) { emit('import', file.value) } }
</script>

<style lang="less" scoped>
:deep(.import-modal .ant-modal-content) {
    padding: 0;
}

:deep(.import-modal .ant-modal-body) {
    padding: 0;
}

.im-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 18px 24px 12px;
    border-bottom: 1px solid #eee;

    .title {
        font-weight: 600;
        font-size: 16px;
    }

    .close {
        color: #1677ff;
        cursor: pointer;
    }
}

.im-body {
    padding: 24px 24px 12px;
    min-height: 120px;
    display: flex;
    align-items: flex-start;

    .row {
        display: flex;
        align-items: flex-start;
        gap: 16px;
    }

    .label {
        width: 72px;
        line-height: 28px;
    }

    .value {
        .tip {
            margin-top: 10px;
            color: #8c8c8c;
        }

        .primary-lite {
            background: #e6efff;
            border-color: #adc6ff;
        }

        .link-del {
            margin-left: 12px;
            color: #1677ff;
            cursor: pointer;
        }
    }
}

.im-footer {
    display: flex;
    justify-content: center;
    align-items: center;
    padding: 14px 0 18px;
    border-top: 1px solid #f0f0f0;

    .cancel,
    .confirm,
    .sep {
        color: #1677ff !important;
    }

    .sep {
        margin: 0 8px;
    }
}
</style>
